package com.hspedu.qqserver.service;

import com.hspedu.qqcommon.Message;
import com.hspedu.qqcommon.MessageType;
import com.hspedu.qqcommon.User;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author 谷其昊
 * @version 1.0
 * @date 2022/3/17
 * @time 20:48
 * 服务端在监听 9999 端口
 * 等待客户端连接并保持通讯
 */
@SuppressWarnings("all")
public class QQServerService {

    /**
     * 服务端保存用户的集合
     */
    private static ConcurrentHashMap<String, User> validUsers = new ConcurrentHashMap<>();

    ServerSocket serverSocket = null;

    /**
     * 从数据库中对用户进行查询
     * @param userId
     * @param password
     * @return
     */
    private boolean checkUser(String userId, String password) {
        User user = validUsers.get(userId);
        if (user == null) {
            return false;
        }
        if (!password.equals(user.getPassword())) {
            return false;
        }
        return true;
    }

    /**
     * 为消息设置发送时间
     * @param message
     */
    public static void setMessageSendTime(Message message){
        LocalDateTime now = LocalDateTime.now();
        String pattern = "yyyy年MM月dd日 HH时mm分ss秒";
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
        String sendTime = dateTimeFormatter.format(now);
        message.setSendTime(sendTime);
    }

    /**
     * 初始化客户端，并对用户登录做校验
     * 登陆成功开启服务器线程
     * 登陆失败返回错误信息并关闭套接字
     */
    public QQServerService() {
        Socket accept = null;
        InputStream inputStream = null;
        ObjectInputStream ois = null;
        Message message = new Message();
        OutputStream os = null;
        ObjectOutputStream oos = null;

        try {
            serverSocket = new ServerSocket(9999);
            while (true) {
                accept = serverSocket.accept();
                inputStream = accept.getInputStream();
                ois = new ObjectInputStream(inputStream);
                User user = (User) ois.readObject();
//                下面这段代码可以再进行优化
//                遍历效率时间复杂度是 O(N)
//                for (String userId : validUsers.keySet()) {
//                    if (userId.equals(user.getUserId())) {
//                        User user1 = validUsers.get(userId);
//                        if (user1.getPassword().equals(user.getPassword())) {
//                            message.setMessageType(MessageType.MESSAGE_LOGIN_SUCCESS);
//                            os = accept.getOutputStream();
//                            oos = new ObjectOutputStream(os);
//                            oos.writeObject(message);
//                            oos.flush();
//                            ServerConnectClientThread thread = new ServerConnectClientThread(accept,userId);
//                            thread.start();
//                            ManageServerConnectClientThread.addServerConnectClientThread(userId, thread);
//                        }
//                    }
//                }
//                说明此时登陆失败
//                if (message.getMessageType() == null){
//                    message.setMessageType(MessageType.MESSAGE_LOGIN_FAIL);
//                    os = accept.getOutputStream();
//                    oos = new ObjectOutputStream(os);
//                    oos.writeObject(message);
//                    oos.flush();
//                    accept.close();
//                }

                /**
                 * 检测登录
                 */
                if (checkUser(user.getUserId(), user.getPassword())) {
                    //说明登陆成功
                    message.setMessageType(MessageType.MESSAGE_LOGIN_SUCCESS);
                    os = accept.getOutputStream();
                    oos = new ObjectOutputStream(os);
                    oos.writeObject(message);
                    oos.flush();
                    ServerConnectClientThread thread = new ServerConnectClientThread(accept, user.getUserId());
                    thread.start();
                    ManageServerConnectClientThread.addServerConnectClientThread(user.getUserId(), thread);
                }else {
                    //登陆失败
                    message.setMessageType(MessageType.MESSAGE_LOGIN_FAIL);
                    os = accept.getOutputStream();
                    oos = new ObjectOutputStream(os);
                    oos.writeObject(message);
                    oos.flush();
                    accept.close();
                }



            }

        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            //退出while循环说明服务器不在监听
            try {
                serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void addUser() {
        validUsers.put("123", new User("123", "123456"));
        validUsers.put("100", new User("100", "123456"));
        validUsers.put("200", new User("200", "123456"));
        validUsers.put("300", new User("300", "123456"));
    }

}
